#include <cstdio>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <cstring>
#include <cstdlib>
#include <string>
//全局变量
//
#define MAXARGC 512
#define FORMAT "[%s@%s %s]$ "
//用户最大输入的命令字符数
#define MAXCMDNUM 1024
// last exit code
int lastcode = 0;
//命令行参数表
int g_argc = 0;
char* g_argv[MAXARGC];


//环境变量表
#define MAX_ENVS 100
char *g_env[MAX_ENVS];
int g_envs = 0;

char cwd[1024];
char cwdenv[4096];

std::string DirName(const char *pwd)
{
#define SLASH "/"
    std::string dir = pwd;
    if(dir == SLASH) return SLASH;
    auto pos = dir.rfind(SLASH);
    if(pos == std::string::npos) return "BUG?";
    return dir.substr(pos+1);
}
const char* GetHome()
{
	const char* home = getenv("HOME");
	return home == NULL ? "None" : home;
}
const char* GetUserName()
{
	const char* user = getenv("USER");
	return user == NULL ? "None" : user;
}
const char* GetHostName()
{
	return "jlf";
}
const char* GetPwd()
{
	//const char *pwd = getenv("PWD");
    const char *pwd = getcwd(cwd, sizeof(cwd));
    if(pwd != NULL)
    {
        snprintf(cwdenv, sizeof(cwdenv), "PWD=%s", cwd);
        putenv(cwdenv);
    }
    return pwd == NULL ? "None" : pwd;
}
//1.打印命令行提示符
void PrintCommandPrompt()
{
	printf(FORMAT,GetUserName(),GetHostName(),DirName(GetPwd()).c_str());
}
//2.获取用户输入的命令
bool GetCommandLine(char* buffer)
{
    // ls -a -l => "ls -a -l\n" 字符串
    char *s = fgets(buffer, MAXCMDNUM, stdin);
    if(s == NULL) return false;
    buffer[strlen(buffer)-1] = 0; // 清理\n
    if(strlen(buffer) == 0) return false;
    return true;
}

// 3. 命令行分析 "ls -a -l" -> "ls" "-a" "-l"
bool CommandLineParse(char *commandline)
{
#define SEP " "
    g_argc = 0;
    // 命令行分析 "ls -a -l" -> "ls" "-a" "-l"
    g_argv[g_argc++] = strtok(commandline, SEP);
    while((bool)(g_argv[g_argc++] = strtok(nullptr, SEP)));
    g_argc--;
    return g_argc > 0 ? true:false;
}

//4.检测并执行内建命令
bool CheckAndExecute()
{
	std::string cmd = g_argv[0];
	if(cmd == "cd")
	{
		if(g_argc == 1)
		{
			chdir(getenv("HOME"));
		}
		else
		{
			chdir(g_argv[1]);
		}
		return true;
	}
	return false;
}

//5.执行命令
void Execute()
{	
	pid_t id = fork();
	if(id == 0)
	{

		execvp(g_argv[0],g_argv);
		exit(1);
	}
	int status = 0;
	//父进程 
	waitpid(id, &status, 0);
	if(WIFEXITED(status))
	{
		lastcode = WEXITSTATUS(status);
	}
	
}
int main()
{
	while(1)
	{
		//1.打印命令行提示符
		PrintCommandPrompt();
		//2.获取用户输入的命令
		char buffer[MAXCMDNUM];
		if(GetCommandLine(buffer))
		{
			//3.分析输入的命令
			if(CommandLineParse(buffer))
			{
				//4.检测并执行内建命令
				if(CheckAndExecute())
					continue;
				//5.执行外部命令	
				Execute();
			}
		}
	}
	return 0;
}
